/**
 * Sprite - 精灵图像类
 * 处理单个精灵图像的渲染和帧管理
 */

export interface SpriteFrame {
  x: number
  y: number
  width: number
  height: number
}

export interface SpriteOptions {
  image: HTMLImageElement
  frameWidth?: number
  frameHeight?: number
  frames?: SpriteFrame[]
  scale?: number
}

export class Sprite {
  public readonly image: HTMLImageElement
  public readonly frameWidth: number
  public readonly frameHeight: number
  public readonly frames: SpriteFrame[]
  public readonly scale: number
  
  private currentFrame: number = 0

  constructor(options: SpriteOptions) {
    this.image = options.image
    this.frameWidth = options.frameWidth || options.image.width
    this.frameHeight = options.frameHeight || options.image.height
    this.scale = options.scale || 1
    
    // 如果没有提供帧数据，创建单帧精灵
    if (options.frames) {
      this.frames = options.frames
    } else {
      this.frames = [{
        x: 0,
        y: 0,
        width: this.frameWidth,
        height: this.frameHeight
      }]
    }
  }

  /**
   * 设置当前帧
   */
  setFrame(frameIndex: number): void {
    if (frameIndex >= 0 && frameIndex < this.frames.length) {
      this.currentFrame = frameIndex
    }
  }

  /**
   * 获取当前帧
   */
  getCurrentFrame(): SpriteFrame {
    return this.frames[this.currentFrame]
  }

  /**
   * 获取帧数量
   */
  getFrameCount(): number {
    return this.frames.length
  }

  /**
   * 渲染精灵到指定位置
   */
  render(
    ctx: CanvasRenderingContext2D,
    x: number,
    y: number,
    width?: number,
    height?: number
  ): void {
    const frame = this.getCurrentFrame()
    const renderWidth = width || this.frameWidth * this.scale
    const renderHeight = height || this.frameHeight * this.scale

    ctx.drawImage(
      this.image,
      frame.x,
      frame.y,
      frame.width,
      frame.height,
      x,
      y,
      renderWidth,
      renderHeight
    )
  }

  /**
   * 创建精灵表精灵（从精灵表中提取多帧）
   */
  static createFromSpriteSheet(
    image: HTMLImageElement,
    frameWidth: number,
    frameHeight: number,
    frameCount: number,
    columns?: number
  ): Sprite {
    const frames: SpriteFrame[] = []
    const cols = columns || Math.floor(image.width / frameWidth)
    
    for (let i = 0; i < frameCount; i++) {
      const col = i % cols
      const row = Math.floor(i / cols)
      
      frames.push({
        x: col * frameWidth,
        y: row * frameHeight,
        width: frameWidth,
        height: frameHeight
      })
    }

    return new Sprite({
      image,
      frameWidth,
      frameHeight,
      frames
    })
  }

  /**
   * 创建单帧精灵
   */
  static createSingle(image: HTMLImageElement, scale?: number): Sprite {
    return new Sprite({
      image,
      scale
    })
  }
}